//factory

/**
 * 非负整数 >= 0
 * @param emptyMessage
 * @param message
 */
const createNonNegativeInteger = (
  emptyMessage = '请输入整数', message = '值必须大于等于0'
) => (rule, value, callback) => {
  if (_.isUndefined(value)) callback();

  const _value = Number(value);
  if (!_.isInteger(_value)) {
    callback(new Error(emptyMessage));
  } else if (_value < 0) {
    callback(new Error(message));
  } else {
    callback();
  }
};
/**
 * 正整数 > 0
 * @param emptyMessage
 * @param message
 */
const createPositiveInteger = (
  emptyMessage = '请输入正整数', message = '值必须大于0'
) => (rule, value, callback) => {
  if (_.isUndefined(value)) callback();

  const _value = Number(value);
  if (!_.isInteger(_value)) {
    callback(new Error(emptyMessage));
  } else if (_value <= 0) {
    callback(new Error(message));
  } else {
    callback();
  }
};
/**
 * 非负数 >= 0
 * @param emptyMessage
 * @param message
 */
const createNonNegativeNumber = (
  emptyMessage = '请输入正数', message = '值必须大于等于0'
) => (rule, value, callback) => {
  if (_.isUndefined(value)) callback();

  const _value = Number(value);
  if (!_.isNumber(_value) || _.isNaN(_value)) {
    callback(new Error(emptyMessage));
  } else if (_value < 0) {
    callback(new Error(message));
  } else {
    callback();
  }
};
/**
 * 正负数保留两位小数,且不能以-0或0开头
 * @param emptyMessage
 * @param message
 */
const createpointsLimit = (
  message = '请输入带两位小数的数字',
) => (rule, value, callback) => {
  if (_.isUndefined(value)) callback();
  const ruleExp = /^-?(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/;
  const ruleExp1 =/^(-0[^.]|0[^.])/;
  if(ruleExp1.test(value)){
    callback(new Error('不能以0开头或-0开头'));
    return;
  }
  if (!ruleExp.test(value)) {
    callback(new Error(message));
  }else {
    callback();
  }
};
/**
 * 不能以-0或0开头的整数
 * @param emptyMessage
 * @param message
 */

const createNoStartWithZero = (
  noZeroMessage = '不能以0开头或-0开头',integerMessage = '请输入整数',
  emptyMessage = '请输入流水',exceedMessage = '长度不能超过12位'
) => (rule, value, callback) => {
  if (_.isUndefined(value)) callback();
  const ruleExp =/^(-0|0)/;

  if(_.trim(value) === ''){
    callback(new Error(emptyMessage));
  }else if(!_.isInteger(Number(value))){
    callback(new Error(integerMessage));
  }else if(ruleExp.test(value)) {
    callback(new Error(noZeroMessage));
  }else if(value.length>12){
    callback(new Error(exceedMessage));
  } else {
    callback();
  }
};
/**
 * 手机号码验证
 * @param emptyMessage
 * @param message
 * @param required
 * @return {Function}
 */
const createMobile = ({required=true,emptyMessage='手机号码不能为空', message = '手机号码格式不对'}) =>(rule,value, callback) =>{
  if (_.isUndefined(value) || _.isEmpty(value)){
    if(required == false){
      callback()
    }else{
      callback(new Error(emptyMessage))
    }
  }
  const reg = /^1(3|4|5|6|7|8|9)\d{9}$/

  if (reg.test(value)) {
    callback()
  } else {
    callback(new Error(message));
  }

};

/**
 * 邮箱验证
 * @param emptyMessage
 * @param message
 */
const createEmail = ({required=true,emptyMessage='邮箱不能为空', message = '邮箱格式不对'}) =>(rule,value, callback) =>{
  var reg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;

  if (_.isUndefined(value) || _.isEmpty(value)){
    if(required == false){
      callback()
    }else{
      callback(new Error(emptyMessage))
    }
  }

  if (!reg.test(value)) {
    callback(new Error(message));
  } else {
    callback();
  }
};
/**
 * 密码验证
 * @param emptyMessage
 * @param message
 */
const createPassword = (emptyMessage='密码不能为空', message = '请输入密码长度在8到20个字符，至少包含“数字/字母/特殊字符”的2种组合') =>(rule,value, callback) =>{
  var reg = /^(?!^\d+$)(?!^[A-Za-z]+$)(?!^[^A-Za-z0-9]+$)(?!^.*[\u4E00-\u9FA5].*$)^\S{8,20}$/;
  if (_.isUndefined(value) || _.isEmpty(value)){
    callback(new Error(emptyMessage))
  }

  if (!reg.test(value)) {
    callback(new Error(message));
  } else {
    callback();
  }
};


/**
 * 合法uri验证
 */
const createUri = (message = 'url格式不正确') =>(rule,value, callback) =>{
  if (_.isEmpty(value)) {
    callback()
  } else {
    const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|vip|cc|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
    if (!urlregex.test(value)) {
      callback(new Error(message));
    } else {
      callback();
    }
  }
}

/**
 * 合法活动uri验证
 */
const createActiveUri = (message = '活动url格式不正确') =>(rule,value, callback) =>{
  if (_.isEmpty(value)) {
    callback()
  } else {
    const urlregex = /\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+)*/
    if (!urlregex.test(value)) {
      callback(new Error(message));
    } else {
      callback();
    }
  }
}

/**
 *
 * 银行卡格式
 */
const createCardNumber = (message = '银行卡号格式不对') =>(rule,value, callback) =>{
  if (_.isEmpty(value)) {
    callback()
  } else {
    const pattern = /^([1-9]{1})(\d{14}|\d{15}|\d{18})$/;
    if (!pattern.test(value)) {
      callback(new Error(message));
    } else {
      callback();
    }
  }
}

/**
 * 正数 >= 0-100
 * @param emptyMessage
 * @param message
 */
const createInRangeFloat = (
  emptyMessage = '请输入数值', message = '数值范围0-100'
) => (rule, value, callback) => {
  if (_.isEmpty(value)) {
    callback();
  } else {
    if (!_.inRange(value, 100)) {
      callback(new Error(message));
    } else {
      callback();
    }
  }
};
/**
 * 字母开头，只能由数字、字母_.组成
 * @param emptyMessage
 * @param message
 */
const createUsername = (
  emptyMessage = '用户名不能为空', message = '字母开头，只能由数字、字母_.组成'
) => (rule, value, callback) => {
  if (_.isEmpty(value)) {
    callback();
  } else {
    var patrn = /^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){5,15}$/;
    if (!patrn.exec(value)) {
      callback(new Error(message));
    } else {
      callback();
    }
  }

}

/**
 * 字母开头，只能由数字、字母_.组成
 * @param emptyMessage
 * @param message
 */
const createAdminUsername = (
  emptyMessage = '用户名不能为空', message = '字母开头，只能由数字、字母_.组成'
) => (rule, value, callback) => {
  if (_.isEmpty(value)) {
    callback();
  } else {
    var patrn = /^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){2,15}$/;
    if (!patrn.exec(value)) {
      callback(new Error(message));
    } else {
      callback();
    }
  }

};

/**
 * 支持保留多位小数
 * @param emptyMessage
 * @param message
 * @param params 指定小数点后的位数
 */
const createProportion = (
  { decimal=0, min=0, max=Infinity }, emptyMessage = '不能为空', errMessage = '请输入正确格式'
) => (rule, value, callback) => {
  const message = (max && max!= Infinity)  ? `数值范围${min}-${max}` : `数值必须大于${min}`;
  const regNoPoint = /^[1-9]\d*$/;
  let regStr;
  decimal>0 ? regStr = '^\\d+[\\.]\\d{1,' + decimal + '}$':null;
  const regHasPoint = new RegExp(regStr);
  const _value = Number(value);
  const valueStr = value.toString();

  if (value === '') {
    callback(new Error(emptyMessage));
  }else if(isNaN(_value)){
    callback(new Error(errMessage));
  } else {
    if(value<min||value>max){
      callback(new Error(message));
    }

    if(decimal===0&&!_.isInteger(_value)){
      callback(new Error('必须为整数'));
    }

    if(decimal>0&&valueStr.indexOf('.')>0){
      // 小数点前的部分
      const strLeft = valueStr.split('.')[0];
      // 小数点后的部分
      const strRight = valueStr.split('.')[1];

      if(strLeft.length>1&&strLeft[0]==0){ // 校验小数点前面有两位数的情况下第一位是否为0
        callback(new Error(errMessage));
      }else if(strRight.length===0) {
        callback(new Error(errMessage));
      }

      if(!regHasPoint.test(valueStr)){
        callback(new Error(errMessage));
      }else{
        callback();
      }
    }else{
      if(_value!=0&&!regNoPoint.test(valueStr)){
        callback(new Error(errMessage));
      }else{
        callback();
      }
    }
  }
};

export {
  createMobile,
  createNonNegativeInteger,
  createNonNegativeNumber,
  createpointsLimit,
  createEmail,
  createPassword,
  createUri,
  createActiveUri,
  createCardNumber,
  createInRangeFloat,
  createUsername,
  createAdminUsername,
  createNoStartWithZero,
  createPositiveInteger,
  createProportion,
};
